package com.zh.lex;

import com.zh.util.StringUtil;

import java.util.*;

public class Lex {
	
	private RE2NFA re = new RE2NFA();
	private Map<Integer, String> typeMap = new HashMap<>();
	private NFA2DFA dfa;


	public void addRole(String type, String role) {
		typeMap.put(re.addEndStat(role), type);
	}

	public void displayGraphviz() {
		dfa.displayGraphviz();
	}

	public List<Token> getTokens(String str) {
		char[] cs = str.toCharArray();
		List<Token> lt = new ArrayList<>();
		int index = 0;
		int line = 0;
		while (index < cs.length) {
			Token t = handleToken(cs, index, line);
			index = t.getEndIndex() + 1;
			line = t.getLine();
			if (null == t.getType()) {
				String v = t.getValue();
				if (StringUtil.isEmply(v))
					continue;
				if (v.length() == 1 && " \n".contains(v))
					continue;
			}
			lt.add(t);
		}
		return lt;
	}

	private Token handleToken(char[] cs, int index, int line) {
		Token t = new Token();
		t.setStartIndex(index);
		t.setLine(line);
		String type = dfa.getType(cs, t);
		t.setType(type);
		t.setValue(new String(cs, t.getStartIndex(), t.getEndIndex() - t.getStartIndex() + 1));
		return t;
	}

	public void handle() {
		re.handle();
		Map<Integer, Integer> change = re.getChangeStat();
		Map<Integer, String> m = new HashMap<>();
		Set<Integer> si = new HashSet<Integer>(change.keySet());
		si.retainAll(typeMap.keySet());
		int size = typeMap.size();
		for (int i : si) {
			String v = typeMap.remove(i);
			typeMap.put(change.get(i), v);
		}
		if (size != typeMap.size())
			throw new IllegalArgumentException();

		dfa = new NFA2DFA(re);
		dfa.setTypeMap(typeMap);
		dfa.handle();

	}

}
